<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>缩放裁剪 5.7</title>
<style>
canvas,#output{border:1px solid gray;margin-top:10px;margin-bottom:10px;}
#set{margin-bottom:5px;}
#big{position:relative;width:0px;height:0px;overflow:hidden;}
#small{left:0px;top:0px;width:100px; height:100px; position:absolute; cursor: move;background:#ffffff;opacity:0;}
#space{position:relative;}
#canvas2{margin-top:5px;}
#m1{left:0px;top:0px;}
#m2{}
#m3{left:0px;}
#m4{left:0px;}
#b1{cursor:n-resize;}
#b2{cursor:ne-resize;}
#b3{cursor:e-resize;}
#b4{cursor:se-resize;}
#b5{cursor:s-resize;}
#b6{cursor:sw-resize;}
#b7{cursor:w-resize;}
#b8{cursor:nw-resize;}
.mask{position:absolute;background:white;opacity:0.3;}
.bh{position:absolute;width:5px;height:5px;border:1px solid blue;}
#copyright{text-align:center;cursor:pointer;}
#about{display:none;z-index:99;position:fixed;left:100px;top:100px;width:80%;height:80%;background:white;border:1px solid gray;overflow-y:scroll;padding-left:2em;}
#closeabout{padding:5px;float:right;cursor:pointer;}
</style>
</head>
<body>
<div id=set><input type=file id=file accept="image/*"><input type=button id=open value=重载> 图片网址：<input type=text id=url><input type=button id=urlbtn value=确定>
裁剪框：宽<input id=cw type=number min=0 value=100> 高<input id=ch type=number min=0 value=100> <input type=button id=zoomout value=-><input id=scale type=number min=0.01 max=0.1 step=0.01 value=0.01><input type=button id=zoomin value=+>  <input type=button id=left value=←> <input type=button id=up value=↑> <input type=button id=down value=↓> <input type=button id=right value=→> <input type=button id=reset value=重置></div>
<div id= "big">
<img src="a.jpg" id="image"/>
</div>
<div id=space>
<div id=small></div>
<div id=m1 class=mask></div>
<div id=m2 class=mask></div>
<div id=m3 class=mask></div>
<div id=m4 class=mask></div>
<div id=b1 class=bh></div>
<div id=b2 class=bh></div>
<div id=b3 class=bh></div>
<div id=b4 class=bh></div>
<div id=b5 class=bh></div>
<div id=b6 class=bh></div>
<div id=b7 class=bh></div>
<div id=b8 class=bh></div>
<canvas id="canvas1" width=1000px height=800px>
Your browser does not support the HTML5 canvas tag.
</canvas>
</div>
<canvas id="canvas2" width=100px height=100px>
Your browser does not support the HTML5 canvas tag.
</canvas>
<img id=output>
<div id=about>
<div id=closeabout>关闭</div>
<h1 align=center>关于</h1>
使用HTML5新功能canvas，对图片进行缩放裁剪。<br>
作者：海天鹰<br>
QQ: 84429027
<h2>V5.7 (2015-10-08)</h2><ol><li>修改关于界面CSS的position为fixed，浮动位置固定，不受滚动影响。</li></ol>
<h2>V5.6 (2015-09-24)</h2><ol><li>使用浮动层显示关于界面</li></ol>
<h2>V5.5 (2015-05-22)</h2><ol><li>缩放后同步裁剪</li><li>缩小不能越过裁剪框</li></ol>
<h2>V5.4 (2015-04-01)</h2><ol><li>解决画布大小不随缩放一起变化的问题</li></ol>
<h2>V5.3 (2015-03-30)</h2><ol><li>增加裁剪框touch事件，使裁剪框拖动兼容手机</li><li>增加上、下、左、右移动裁剪框的按钮，以兼容手机</li><li>更改缩放控制方式为按钮，以兼容手机</li></ol>
<h2>V5.2 (2015-03-29)</h2><ol><li>增加裁剪框角点拖动，修复裁剪边框拖动BUG</li></ol>
<h2>V5.1 (2015-03-28)</h2><ol><li>修复裁剪边框拖动BUG</li></ol>
<h2>V5.0 (2015-03-27)</h2><ol><li>增加载入网络图片，已知问题：换图片后canvas2.toDataURL('image/jpeg')不工作了。</li><li>增加载入本地图片</li></ol>
<h2>V4.0 (2015-03-26)</h2><ol><li>增加裁剪边框中点拖动，addEventListener("mousedown",function(event){b1_down(event);}, false)，Firefox需要function(event)传递event参数而且很卡，Chrome不需要直接function(){b1_down(event);}而且很流畅。</li></ol>
<h2>V3.0 (2015-03-25)</h2><ol><li>初步实现缩放裁剪</li><li>发现遮罩层BUG并修复，实现遮罩效果。</li><li>发现缩放回车键BUG并修复。</li><li>canvas.toDataURL('image/jpeg')把默认的png格式转换成jpg格式的方法，Firefox可以，Chrome服务器端同域可以，本地和异域报错：Tainted canvases may not be exported.</li></ol>
<h2>V2.0 (2015-03-24)</h2><ol><li>可定制裁剪框大小</li></ol>
<h2>V1.0 (2015-03-23)</h2><ol><li>融合拖动和裁剪功能</li></ol>
</div>
<p id=copyright>&copy;&nbsp;Copyright 2015-2017 版权所有 海天鹰工作室<p>
</body>
<script>
var obig=document.getElementById("big");
var osmall=document.getElementById("small");
var m1=document.getElementById("m1");
var m2=document.getElementById("m2");
var m3=document.getElementById("m3");
var m4=document.getElementById("m4");
var space=document.getElementById("space");
var canvas1=document.getElementById("canvas1");
var ctx1=canvas1.getContext("2d");
var canvas2=document.getElementById("canvas2");
var ctx2=canvas2.getContext("2d");
var img=document.getElementById("image");
var imgout=document.getElementById("output");
var cw=document.getElementById("cw");
var ch=document.getElementById("ch");
var b1=document.getElementById("b1");
var b2=document.getElementById("b2");
var b3=document.getElementById("b3");
var b4=document.getElementById("b4");
var b5=document.getElementById("b5");
var b6=document.getElementById("b6");
var b7=document.getElementById("b7");
var b8=document.getElementById("b8");

function small_down(e){	
	var e=e||window.event;		
	document.onmousemove=small_move;
	document.onmouseup=small_up;
	osmall.startX=e.clientX-osmall.offsetLeft;
	osmall.startY=e.clientY-osmall.offsetTop;	
}
function small_move(e){
	var e=e||window.event;	
	osmall.style.left=e.clientX-osmall.startX+"px";
	osmall.style.top=e.clientY-osmall.startY+"px";
	var wbs=canvas1.offsetWidth-osmall.offsetWidth;
	var hbs=canvas1.offsetHeight-osmall.offsetHeight;
	if(e.clientX-osmall.startX<=0){ osmall.style.left=0+"px";}
	if(e.clientY-osmall.startY<=0){ osmall.style.top=0+"px";}
	if(e.clientX-osmall.startX>=wbs){ osmall.style.left=wbs+"px";}
	if(e.clientY-osmall.startY>=hbs){ osmall.style.top=hbs+"px";}
	mask();
	cut();
}
function small_up(){
	document.onmousemove="";
	document.onmouseup="";
}
osmall.addEventListener("mousedown",function(event){small_down(event);}, false);

var startX=0,startY=0;
function touchStart(event) {    
    //阻止网页默认动作（即网页滚动）
    event.preventDefault();
   // if (spirit || !event.touches.length) return;
    var touch = event.touches[0];
	startX = touch.pageX-osmall.offsetLeft;
    startY = touch.pageY-osmall.offsetTop;
}
function touchMove(event) {
    event.preventDefault();
    var touch = event.touches[0];
	console.log(osmall.offsetTop);
    osmall.style.left = touch.pageX-startX + "px";
    osmall.style.top = touch.pageY-startY + "px";
	if(osmall.offsetLeft<0){osmall.style.left=0+"px";}
    if(osmall.offsetTop<0){osmall.style.top=0+"px";}	
	var wbs=canvas1.offsetWidth-osmall.offsetWidth;
	var hbs=canvas1.offsetHeight-osmall.offsetHeight;
	if(osmall.offsetLeft>=wbs){ osmall.style.left=wbs+"px";}
	if(osmall.offsetTop>=hbs){ osmall.style.top=hbs+"px";}
	mask();
	cut();
}
function touchEnd(event) {
    
}
osmall.addEventListener("touchstart",function(event){touchStart(event);}, false);
osmall.addEventListener("touchmove", function(event){touchMove(event);}, false);
osmall.addEventListener("touchend", function(event){touchEnd(event);}, false);

function b1_down(e){
	//var e=e||window.event;	
	document.onmousemove=b1_move;
	document.onmouseup=small_up;
	b1.startY=osmall.offsetTop+osmall.offsetHeight;
}
function b1_move(e){
	//var e=e||window.event;	
	var hn=b1.startY-e.pageY+space.offsetTop;
	
	if(hn>0 && e.pageY>0){
		osmall.style.top=e.pageY-space.offsetTop+"px";		
		osmall.style.height=hn+"px";
		ch.value=hn;
		canvas2.height=hn;
	}	
	mask();
	cut();
}
b1.addEventListener("mousedown",function(event){b1_down(event);}, false);

function b2_down(e){
	document.onmousemove=b2_move;
	document.onmouseup=small_up;
	b2.startX=osmall.offsetLeft;
	b2.startY=osmall.offsetTop+osmall.offsetHeight;
}
function b2_move(e){
	var wn=e.pageX-b2.startX-8;
	var hn=b2.startY+space.offsetTop-e.pageY;
	if(wn>0&&hn>0&&e.pageX<canvas1.offsetWidth+8&&e.pageY>=space.offsetTop){
		osmall.style.top=e.pageY-space.offsetTop+"px";
		osmall.style.width=wn+"px";
		osmall.style.height=hn+"px";
		cw.value=wn;
		ch.value=hn;
		canvas2.width=wn;
		canvas2.height=hn;
	}
	mask();
	cut();
}
b2.addEventListener("mousedown",function(event){b2_down(event);}, false);

function b3_down(e){
	//var e=e||window.event;	
	document.onmousemove=b3_move;
	document.onmouseup=small_up;
	b3.startX=osmall.offsetLeft;
}
function b3_move(e){
	//var e=e||window.event;	
	var wn=e.pageX-b3.startX-8;
	if(wn>0&&e.pageX<canvas1.offsetWidth+8){		
		osmall.style.width=wn+"px";
		cw.value=wn;
		canvas2.width=wn;
	}
	mask();
	cut();
}
b3.addEventListener("mousedown",function(event){b3_down(event);}, false);

function b4_down(e){
	document.onmousemove=b4_move;
	document.onmouseup=small_up;
	b4.startX=osmall.offsetLeft;
	b4.startY=osmall.offsetTop;
}
function b4_move(e){
	var wn=e.pageX-b4.startX-8;
	var hn=e.pageY-b4.startY-space.offsetTop;
	if(wn>0&&hn>0&&e.pageX<canvas1.offsetWidth+8&&e.pageY<=canvas1.offsetHeight+space.offsetTop){
		osmall.style.width=wn+"px";	
		osmall.style.height=hn+"px";
		cw.value=wn;
		ch.value=hn;
		canvas2.width=wn;
		canvas2.height=hn;
	}
	mask();
	cut();
}
b4.addEventListener("mousedown",function(event){b4_down(event);}, false);

function b5_down(e){
	document.onmousemove=b5_move;
	document.onmouseup=small_up;
	b5.startY=osmall.offsetTop;
}
function b5_move(e){
//var e=e||window.event; 
	var hn=e.pageY-b5.startY-space.offsetTop;
	if(hn>0&&e.pageY<=canvas1.offsetHeight+space.offsetTop){		
		osmall.style.height=hn+"px";
		ch.value=hn;
		canvas2.height=hn;		
	}
	mask();
	cut();
}
b5.addEventListener("mousedown",function(event){b5_down(event);}, false);

function b6_down(e){
	document.onmousemove=b6_move;
	document.onmouseup=small_up;
	b6.startX=osmall.offsetLeft+osmall.offsetWidth+8;
	b6.startY=osmall.offsetTop+space.offsetTop;
}
function b6_move(e){
	var wn=b6.startX-e.pageX;
	var hn=e.pageY-b6.startY;
	if(wn>0&&hn>0&&e.pageX>=8&&e.pageY<=canvas1.offsetHeight+space.offsetTop){
		osmall.style.left=e.pageX-8+"px";
		osmall.style.width=wn+"px";
		osmall.style.height=hn+"px";
		cw.value=wn;
		ch.value=hn;
		canvas2.width=wn;
		canvas2.height=hn;
	}
	mask();
	cut();
}
b6.addEventListener("mousedown",function(event){b6_down(event);}, false);

function b7_down(e){
	document.onmousemove=b7_move;
	document.onmouseup=small_up;
	b7.startX=osmall.offsetLeft+osmall.offsetWidth;
}
function b7_move(e){
//var e=e||window.event;	
	var wn=b7.startX-e.pageX+8;
	if(wn>0&&e.pageX>0){
		osmall.style.left=e.pageX-8+"px";
		osmall.style.width=wn+"px";
		cw.value=wn;
		canvas2.width=wn;
	}
	mask();
	cut();
}
b7.addEventListener("mousedown",function(event){b7_down(event);}, false);

function b8_down(e){
	document.onmousemove=b8_move;
	document.onmouseup=small_up;
	b8.startX=osmall.offsetLeft+osmall.offsetWidth+8;
	b8.startY=osmall.offsetTop+osmall.offsetHeight+space.offsetTop;
}
function b8_move(e){
	var wn=b8.startX-e.pageX;
	var hn=b8.startY-e.pageY;
	if(wn>0&&hn>0&&e.pageX>=8&&e.pageY>=space.offsetTop){
		osmall.style.left=e.pageX-8+"px";
		osmall.style.top=e.pageY-space.offsetTop+"px";
		osmall.style.width=wn+"px";
		osmall.style.height=hn+"px";
		cw.value=wn;
		ch.value=hn;
		canvas2.width=wn;
		canvas2.height=hn;
	}
	mask();
	cut();
}
b8.addEventListener("mousedown",function(event){b8_down(event);}, false);

function mask(){
	m1.style.width=canvas1.offsetWidth+"px";		
	m1.style.height=osmall.offsetTop+"px";
	m2.style.left=osmall.offsetLeft+osmall.offsetWidth+"px";
	m2.style.top=osmall.offsetTop+"px";
	m2.style.width=canvas1.offsetWidth-osmall.offsetLeft-osmall.offsetWidth+"px";		
	m2.style.height=osmall.offsetHeight+"px";		
	m3.style.top=osmall.offsetTop+osmall.offsetHeight+"px";
	m3.style.width=canvas1.offsetWidth+"px";		
	m3.style.height=canvas1.offsetHeight-osmall.offsetTop-osmall.offsetHeight+"px";
	m4.style.top=osmall.offsetTop+"px";
	m4.style.width=osmall.offsetLeft+"px";		
	m4.style.height=osmall.offsetHeight+"px";
	b1.style.left=osmall.offsetLeft+osmall.offsetWidth/2-b1.offsetWidth/2+"px";
	b1.style.top=osmall.offsetTop-b1.offsetWidth/2+"px";
	b2.style.left=osmall.offsetLeft+osmall.offsetWidth-b1.offsetWidth/2+"px";
	b2.style.top=osmall.offsetTop-b1.offsetWidth/2+"px";
	b3.style.left=osmall.offsetLeft+osmall.offsetWidth-b1.offsetWidth/2+"px";
	b3.style.top=osmall.offsetTop+osmall.offsetHeight/2-b1.offsetWidth/2+"px";
	b4.style.left=osmall.offsetLeft+osmall.offsetWidth-b1.offsetWidth/2+"px";
	b4.style.top=osmall.offsetTop+osmall.offsetHeight-b1.offsetWidth/2+"px";
	b5.style.left=osmall.offsetLeft+osmall.offsetWidth/2-b1.offsetWidth/2+"px";
	b5.style.top=osmall.offsetTop+osmall.offsetHeight-b1.offsetWidth/2+"px";
	b6.style.left=osmall.offsetLeft-b1.offsetWidth/2+"px";
	b6.style.top=osmall.offsetTop+osmall.offsetHeight-b1.offsetWidth/2+"px";
	b7.style.left=osmall.offsetLeft-b1.offsetWidth/2+"px";
	b7.style.top=osmall.offsetTop+osmall.offsetHeight/2-b1.offsetWidth/2+"px";
	b8.style.left=osmall.offsetLeft-b1.offsetWidth/2+"px";
	b8.style.top=osmall.offsetTop-b1.offsetWidth/2+"px";
}

function cut(){	
	//imgout.crossOrigin = "Anonymous";
	//imgout.setAttribute('crossOrigin', 'anonymous');
	ctx2.drawImage(canvas1,osmall.offsetLeft,osmall.offsetTop,osmall.offsetWidth,osmall.offsetHeight,0,0,osmall.offsetWidth,osmall.offsetHeight);
	var dataURL= canvas2.toDataURL('image/jpeg');
	imgout.src=dataURL;
}

cw.addEventListener("change",function(){
	if(this.value<1)this.value=1;
	if(this.value>img.offsetWidth)this.value=img.offsetWidth;
	osmall.style.width=this.value+"px";
	canvas2.width=this.value;
	mask();
	cut();
}, false);

ch.addEventListener("change",function(){
	if(this.value<1)this.value=1;
	if(this.value>img.offsetHeight)this.value=img.offsetHeight;
	osmall.style.height=this.value+"px";
	canvas2.height=this.value;
	mask();
	cut();
}, false);

document.getElementById("scale").addEventListener("change",function(){
	if(this.value<0)this.value=0;
	if(this.value>0.1)this.value=0.1;
}, false);
document.getElementById("zoomin").addEventListener("click",function(){
	var scale=parseFloat(document.getElementById("scale").value);
	if(scale<0)scale=0;
	if(scale>0.1)scale=0.1;
	scale=1+scale;	
	ctx1.scale(scale,scale);	
	canvas1.width=canvas1.offsetWidth*scale;
	canvas1.height=canvas1.offsetHeight*scale;
	ctx1.drawImage(img,0,0,canvas1.width,canvas1.height);	
	mask();
	cut();
}, false);
document.getElementById("zoomout").addEventListener("click",function(){
	var scale=parseFloat(document.getElementById("scale").value);
	if(scale<0)scale=0;
	if(scale>0.1)scale=0.1;
	scale=1-scale;
	var osmallbottom=osmall.offsetTop+osmall.offsetHeight;
	var osmallright=osmall.offsetLeft+osmall.offsetWidth;
	if(canvas1.offsetWidth*scale>osmallright && canvas1.offsetHeight*scale>osmallbottom){
		ctx1.scale(scale,scale);
		canvas1.width=canvas1.offsetWidth*scale;
		canvas1.height=canvas1.offsetHeight*scale;
		ctx1.drawImage(img,0,0,canvas1.width,canvas1.height);
		mask();
		cut();
	}
}, false);

document.getElementById("reset").addEventListener("click",function(){
	ctx1.scale(2,2);	
	ctx1.drawImage(img,0,0);
}, false);

document.getElementById("urlbtn").addEventListener("click",function(){
	img.src=document.getElementById("url").value;
	init();
}, false);

function read(){
	file = document.getElementById('file').files[0];
	var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function(e){
		img.src=reader.result;
		img.onload=function(e){init();mask();cut();}
	};	
}
document.getElementById("open").addEventListener("click",function(){read();}, false);
document.getElementById("file").addEventListener("change",function(){read();}, false);

document.getElementById("up").addEventListener("mousedown",function(e){	
	if(osmall.offsetTop>0){
		osmall.style.top=osmall.offsetTop-1+'px';
		mask();
		cut();
	}	
}, false);

document.getElementById("down").addEventListener("mousedown",function(e){	
	if(osmall.offsetTop<canvas1.offsetHeight-osmall.offsetHeight){
		osmall.style.top=osmall.offsetTop+1+'px';
		mask();
		cut();
	}	
}, false);

document.getElementById("left").addEventListener("mousedown",function(e){	
	if(osmall.offsetLeft>0){
		osmall.style.left=osmall.offsetLeft-1+'px';
		mask();
		cut();
	}	
}, false);
document.getElementById("right").addEventListener("mousedown",function(e){	
	if(osmall.offsetLeft<canvas1.offsetWidth-osmall.offsetWidth){
		osmall.style.left=osmall.offsetLeft+1+'px';
		mask();
		cut();
	}	
}, false);

function init(){
	//osmall.style.left="0px";
	//osmall.style.top="0px";
	canvas1.width=img.offsetWidth;
	canvas1.height=img.offsetHeight;
	ctx1.drawImage(img,0,0);
	document.getElementById("cw").setAttribute("max",img.offsetWidth);
	document.getElementById("ch").setAttribute("max",img.offsetHeight);
}

window.onload=function(){
	init();
}
document.getElementById("copyright").addEventListener("click",function(){document.getElementById("about").style.display='block';}, false);
document.getElementById("closeabout").addEventListener("click",function(){document.getElementById("about").style.display='none';}, false);
</script>
</html>
